package ynu.edu.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.crypto.digest.BCrypt;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ynu.edu.common.exception.BusinessException;
import ynu.edu.user.dto.UserDTO;
import ynu.edu.user.dto.UserLoginDTO;
import ynu.edu.user.entity.User;
import ynu.edu.user.repository.UserRepository;
import ynu.edu.user.service.UserService;
import ynu.edu.user.util.JwtUtil;
import ynu.edu.user.vo.UserVO;

/**
 * 用户服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {

    private final UserRepository userRepository;
    private final JwtUtil jwtUtil;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserVO register(UserDTO userDTO) {
        // 检查用户名是否已存在
        if (userRepository.existsByUsername(userDTO.getUsername())) {
            throw new BusinessException("用户名已存在");
        }

        // 检查手机号是否已存在
        if (userDTO.getPhone() != null && userRepository.existsByPhone(userDTO.getPhone())) {
            throw new BusinessException("手机号已存在");
        }

        // 检查邮箱是否已存在
        if (userDTO.getEmail() != null && userRepository.existsByEmail(userDTO.getEmail())) {
            throw new BusinessException("邮箱已存在");
        }

        // 创建用户实体
        User user = new User();
        BeanUtil.copyProperties(userDTO, user, "id", "password");

        // 加密密码
        user.setPassword(BCrypt.hashpw(userDTO.getPassword()));

        // 保存用户
        user = userRepository.save(user);

        // 返回用户信息
        UserVO userVO = new UserVO();
        BeanUtil.copyProperties(user, userVO);
        return userVO;
    }

    @Override
    public String login(UserLoginDTO loginDTO) {
        // 根据用户名查询用户
        User user = userRepository.findByUsername(loginDTO.getUsername())
                .orElseThrow(() -> new BusinessException("用户名或密码错误"));

        // 验证密码
        if (!BCrypt.checkpw(loginDTO.getPassword(), user.getPassword())) {
            throw new BusinessException("用户名或密码错误");
        }

        // 检查用户状态
        if (user.getStatus() == 0) {
            throw new BusinessException("账号已被禁用");
        }

        // 生成JWT令牌
        return jwtUtil.generateToken(user.getUsername(), user.getId());
    }

    @Override
    public UserVO getUserInfo(Long id) {
        User user = userRepository.findById(id)
                .orElseThrow(() -> new BusinessException("用户不存在"));

        UserVO userVO = new UserVO();
        BeanUtil.copyProperties(user, userVO);
        return userVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserVO updateUserInfo(UserDTO userDTO) {
        // 查询用户
        User user = userRepository.findById(userDTO.getId())
                .orElseThrow(() -> new BusinessException("用户不存在"));

        // 检查手机号是否已存在
        if (userDTO.getPhone() != null && !userDTO.getPhone().equals(user.getPhone()) &&
                userRepository.existsByPhone(userDTO.getPhone())) {
            throw new BusinessException("手机号已存在");
        }

        // 检查邮箱是否已存在
        if (userDTO.getEmail() != null && !userDTO.getEmail().equals(user.getEmail()) &&
                userRepository.existsByEmail(userDTO.getEmail())) {
            throw new BusinessException("邮箱已存在");
        }

        // 更新用户信息
        BeanUtil.copyProperties(userDTO, user, "id", "username", "password", "status");

        // 保存用户
        user = userRepository.save(user);

        // 返回用户信息
        UserVO userVO = new UserVO();
        BeanUtil.copyProperties(user, userVO);
        return userVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updatePassword(Long id, String oldPassword, String newPassword) {
        // 查询用户
        User user = userRepository.findById(id)
                .orElseThrow(() -> new BusinessException("用户不存在"));

        // 验证旧密码
        if (!BCrypt.checkpw(oldPassword, user.getPassword())) {
            throw new BusinessException("旧密码错误");
        }

        // 更新密码
        user.setPassword(BCrypt.hashpw(newPassword));
        userRepository.save(user);

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteUser(Long id) {
        // 查询用户
        User user = userRepository.findById(id)
                .orElseThrow(() -> new BusinessException("用户不存在"));

        // 逻辑删除
        user.setIsDeleted(1);
        userRepository.save(user);

        return true;
    }
    
    @Override
    public UserVO getUserByPhone(String phone) {
        User user = userRepository.findByPhone(phone)
                .orElseThrow(() -> new BusinessException("用户不存在"));
                
        UserVO userVO = new UserVO();
        BeanUtil.copyProperties(user, userVO);
        return userVO;
    }
    
    @Override
    public UserVO getUserByEmail(String email) {
        User user = userRepository.findByEmail(email)
                .orElseThrow(() -> new BusinessException("用户不存在"));
                
        UserVO userVO = new UserVO();
        BeanUtil.copyProperties(user, userVO);
        return userVO;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUserStatus(Long id, Integer status) {
        // 检查状态值是否有效
        if (status != 0 && status != 1) {
            throw new BusinessException("无效的状态值，只能为0(禁用)或1(启用)");
        }
        
        // 查询用户
        User user = userRepository.findById(id)
                .orElseThrow(() -> new BusinessException("用户不存在"));
                
        // 更新状态
        user.setStatus(status);
        userRepository.save(user);
        
        return true;
    }
} 